package org.madmac.usuario;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.madmac.exception.EncryptPasswordFailedException;
import org.madmac.exception.UserAlreadyRegisteredException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.PreparedStatement;
import org.madmac.modulo.EModulo;
import org.wakeful.conn.Connection;

public class UsuarioDao {

	private static UsuarioDao instance;

	private UsuarioDao() {
	}

	public static UsuarioDao getInstance() {

		if (instance == null) {
			instance = new UsuarioDao();
		}

		return instance;
	}

   /**
    *
    * @param pessoa
    * @param modulo
    * @return
    * @throws SQLException
    * @throws ClassNotFoundException
    * @throws UserAlreadyRegisteredException
    * @throws Exception
    * @deprecated Use create(Usuario)
    */
	public boolean insertUsuario(String pessoa, int modulo)
			  throws SQLException, ClassNotFoundException, UserAlreadyRegisteredException, Exception {

		Usuario usuario = verificaUsuarioCadastrado(pessoa);
		if (usuario != null) {

			java.sql.Connection conn = Connection.getInstance();
			Statement stmt = conn.createStatement();
			String sql = "INSERT INTO madmac.usuarios (code_usuario, modulo) ";
			sql += "VALUES (" + usuario + ", " + modulo + ") ";

			int result = stmt.executeUpdate(sql);

			if (result == 1) {
				return true;
			} else {
				return false;
			}

		} else {
			throw new UserAlreadyRegisteredException("Usuário já cadastrado.");
		}
	}

	public Usuario verificaUsuarioCadastrado(String pessoa) throws SQLException, ClassNotFoundException, Exception {

		Usuario usuario = null;

		java.sql.Connection conn = Connection.getInstance();
		Statement stmt = conn.createStatement();
		String sql = "SELECT uu.code_usuario FROM unify.usuarios uu, unify.pessoas up ";
		sql += "WHERE uu.code_pessoa = up.code_pessoa ";
		sql += "AND up.nome = (SELECT UPPER('" + pessoa + "')) ";

		ResultSet rs = null;
		try {
			rs = stmt.executeQuery(sql);
		} catch (Exception e) {
			return null;
		}

		if (rs.next()) {
			usuario = new Usuario();
			//usuario.setCode_usuario(rs.getInt("code_usuario"));
		}
		return usuario;
	}

	public String encriptarSenha(String senha) throws EncryptPasswordFailedException {

		String md5 = "";
		MessageDigest md = null;

		try {
			md = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			throw new EncryptPasswordFailedException("Falha ao encriptar a senha.");
		}

		BigInteger hash = new BigInteger(1, md.digest(senha.getBytes()));
		md5 = hash.toString(16);

		return md5;
	}

	public Usuario selectByNome(String search_nome) throws SQLException, ClassNotFoundException, Exception {

		Usuario usuario = null;

		java.sql.Connection conn = Connection.getInstance();
		Statement stmt = conn.createStatement();

		String sql = "SELECT up.nome, mm.descricao AS modulo ";
		sql += "FROM unify.pessoas up, madmac.modulos mm, madmac.usuarios mu, unify.usuarios uu ";
		sql += "WHERE mu.modulo = mm.code_modulo ";
		sql += "AND mu.code_usuario = uu.code_usuario ";
		sql += "AND uu.code_pessoa = up.code_pessoa ";
		sql += "AND up.nome = '" + search_nome.toUpperCase() + "' ";

		ResultSet rs = null;
		try {
			rs = stmt.executeQuery(sql);
		} catch (Exception e) {
			return null;
		}

		if (rs.next()) {

			usuario = new Usuario();

			usuario.setNickname(rs.getString("nome"));
			usuario.setModulo(EModulo.valueOf(rs.getString("modulo")));
		}

		return usuario;
	}

   // TODO: implementar cria usuario.
   public Object create (Usuario usuario) throws Exception {
      Integer id = null;
      PreparedStatement pstmt = null;
      ResultSet rs = null;
      try {
         java.sql.Connection conn = Connection.getInstance();
         pstmt = conn.prepareStatement(UsuarioQuery.create());
         pstmt.setString(1, usuario.getLogin());
         pstmt.setString(2, usuario.getSenha());
         pstmt.setString(3, usuario.getNickname());
         pstmt.setInt(4, usuario.getPessoa().getIdPessoa());
         pstmt.setInt(5, usuario.getModulo().id());
         rs = pstmt.executeQuery();
         if (rs.next()) {
            id = rs.getInt("id_usuario");
         }
      } catch (Exception e) {
         throw new Exception(e);
      } finally {
         if (pstmt != null) {
            pstmt.close();
         }
         if (rs != null) {
            rs.close();
         }
      }
      return id;
   }

   public Usuario findById(int idUsuario) throws Exception {
      Usuario usuario = null;
      PreparedStatement pstmt = null;
      ResultSet rs = null;
      try {
         java.sql.Connection conn = Connection.getInstance();
         pstmt = conn.prepareStatement(UsuarioQuery.retrieve());
         pstmt.setInt(1, idUsuario);
         rs = pstmt.executeQuery();
         if (rs.next()) {
            usuario = new Usuario();
            // setters.
            usuario.setLogin(rs.getString("login"));
            usuario.setNickname(rs.getString("nickname"));
            usuario.getPessoa().setIdPessoa(rs.getInt("id_pessoa"));
            usuario.getPessoa().setNome(rs.getString("nome"));
            usuario.setModulo(EModulo.valueOf(rs.getString("modulo")));
         }
      } catch (Exception e) {
         throw new Exception(e);
      } finally {
         if (pstmt != null) {
            pstmt.close();
         }
         if (rs != null) {
            rs.close();
         }
      }
      return usuario;
   }
}
